package org.jeecg.modules.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.oms.entity.CfProfileMaterial;
import org.jeecg.modules.oms.entity.ProductSalesOrder;
import org.jeecg.modules.oms.entity.XingeProfileCutDetail;
import org.jeecg.modules.oms.mapper.CfProfileMaterialMapper;
import org.jeecg.modules.oms.mapper.ProductSalesOrderMapper;
import org.jeecg.modules.oms.mapper.XingeProfileCutDetailMapper;
import org.jeecg.modules.wms.entity.WmsMaterial;
import org.jeecg.modules.wms.mapper.WmsMaterialMapper;
import org.jeecg.modules.wms.service.ISurplusMaterialService;
import org.jeecg.modules.wms.vo.SurplusMaterialVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 余料服务实现类
 */
@Slf4j
@Service
public class SurplusMaterialServiceImpl implements ISurplusMaterialService {
    
    @Autowired
    private ProductSalesOrderMapper productSalesOrderMapper;
    
    @Autowired
    private CfProfileMaterialMapper cfProfileMaterialMapper;
    
    @Autowired
    private XingeProfileCutDetailMapper xingeProfileCutDetailMapper;
    
    @Autowired
    private WmsMaterialMapper wmsMaterialMapper;
    
    @Autowired
    private org.jeecg.modules.wms.config.SurplusInboundConfig surplusInboundConfig;
    
    @Override
    public List<SurplusMaterialVO> getSurplusMaterialsByOrderId(String orderId) {
        // 查询订单信息
        ProductSalesOrder order = productSalesOrderMapper.selectById(orderId);
        if (order == null) {
            throw new JeecgBootException("订单不存在");
        }
        
        List<SurplusMaterialVO> surplusMaterials = new ArrayList<>();
        
        // 根据优化软件类型查询余料信息
        Integer optimizationSoftwareType = order.getOptimizationSoftwareType();
        if (optimizationSoftwareType == null) {
            log.warn("订单[{}]未设置优化软件类型，默认使用长风软件类型", orderId);
            optimizationSoftwareType = 0; // 默认使用长风软件
        }
        
        if (optimizationSoftwareType == 0) {
            // 长风软件类型
            surplusMaterials = getCfSurplusMaterials(orderId);
        } else if (optimizationSoftwareType == 1) {
            // 新格尔软件类型
            surplusMaterials = getXgeSurplusMaterials(orderId);
        } else {
            log.warn("不支持的优化软件类型: {}", optimizationSoftwareType);
        }
        
        return surplusMaterials;
    }
    
    /**
     * 获取长风系统的余料信息
     */
    private List<SurplusMaterialVO> getCfSurplusMaterials(String orderId) {
        List<SurplusMaterialVO> result = new ArrayList<>();
        
        // 查询长风系统余料信息
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<CfProfileMaterial> wrapper = 
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        wrapper.eq(CfProfileMaterial::getOrderId, orderId);
        wrapper.ne(CfProfileMaterial::getLeftLength, 0);
        List<CfProfileMaterial> cfMaterials = cfProfileMaterialMapper.selectList(wrapper);
        ConcurrentHashMap<String, WmsMaterial> wmsMaterialHashMap = new ConcurrentHashMap<>();
        
        for (CfProfileMaterial material : cfMaterials) {
            if (material.getLeftLength() != null && material.getLeftLength() > 0) {
                // 查询物料信息获取余料下限
                WmsMaterial materialInfo;
                if(wmsMaterialHashMap.containsKey(material.getProfileCode())){
                    materialInfo = wmsMaterialHashMap.get(material.getProfileCode());
                } else {
                    materialInfo = wmsMaterialMapper.selectOne(new QueryWrapper<WmsMaterial>().eq("material_code", material.getProfileCode()));
                    if(materialInfo != null){
                        wmsMaterialHashMap.put(material.getProfileCode(), materialInfo);
                    }
                }
                
                // 根据余料下限进行筛选
                if (materialInfo != null) {
                    BigDecimal remnantLower = materialInfo.getRemnantLower();
                    // 如果物料没有设置余料下限，则默认为不保存余料，跳过该余料
                    if (remnantLower == null || remnantLower.compareTo(BigDecimal.ZERO) <= 0) {
                        log.debug("物料[{}]未设置余料下限或余料下限为0，跳过余料长度[{}]", material.getProfileCode(), material.getLeftLength());
                        continue;
                    }
                    
                    // 如果余料长度小于余料下限，则不保存该余料
                    if (BigDecimal.valueOf(material.getLeftLength()).compareTo(remnantLower) < 0) {
                        log.debug("物料[{}]余料长度[{}]小于余料下限[{}]，跳过该余料", material.getProfileCode(), material.getLeftLength(), remnantLower);
                        continue;
                    }
                } else {
                    // 如果找不到物料信息，默认不保存余料
                    log.warn("未找到物料[{}]的信息，跳过该余料", material.getProfileCode());
                    continue;
                }
                
                SurplusMaterialVO vo = new SurplusMaterialVO();
                vo.setProfileCode(material.getProfileCode());
                vo.setProfileName(material.getProfileName());
                vo.setSurplusLength(material.getLeftLength());
                vo.setOptimizationSoftwareType(0);
                
                // 设置单位成本
                if (materialInfo.getUnitCost() != null) {
                    //余料单位成本 = 物料单位成本/物料长度 * 余料长度
                    vo.setUnitCost(materialInfo.getUnitCost().divide(BigDecimal.valueOf(material.getLength()),
                            2,
                            BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(vo.getSurplusLength())));
                }
                
                // 生成余料编号
                vo.setMaterialCode(material.getProfileCode() + "-" + material.getLeftLength().intValue());
                
                // 设置物料类型为余料(5)
                vo.setMaterialType("5");
                
                // 查询物料信息获取规格和单位
                setMaterialInfo(vo);
                
                result.add(vo);
            }
        }
        
        return result;
    }
    
    /**
     * 获取新格尔系统的余料信息
     */
    private List<SurplusMaterialVO> getXgeSurplusMaterials(String orderId) {
        List<SurplusMaterialVO> result = new ArrayList<>();
        
        // 查询新格尔系统余料信息
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<XingeProfileCutDetail> wrapper = 
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        wrapper.like(XingeProfileCutDetail::getOrderId, orderId);
        wrapper.ne(XingeProfileCutDetail::getRemnant, 0);
        List<XingeProfileCutDetail> xgeMaterials = xingeProfileCutDetailMapper.selectList(wrapper);
        ConcurrentHashMap<String, WmsMaterial> wmsMaterialHashMap = new ConcurrentHashMap<>();
        
        for (XingeProfileCutDetail material : xgeMaterials) {
            if (material.getRemnant() != null && material.getRemnant() > 0) {
                // 查询物料信息获取余料下限
                WmsMaterial materialInfo;
                if(wmsMaterialHashMap.containsKey(material.getProfileCode())){
                    materialInfo = wmsMaterialHashMap.get(material.getProfileCode());
                } else {
                    materialInfo = wmsMaterialMapper.selectOne(new QueryWrapper<WmsMaterial>().eq("material_code", material.getProfileCode()));
                    if(materialInfo != null){
                        wmsMaterialHashMap.put(material.getProfileCode(), materialInfo);
                    }
                }
                
                // 根据余料下限进行筛选
                if (materialInfo != null) {
                    BigDecimal remnantLower = materialInfo.getRemnantLower();
                    // 如果物料没有设置余料下限，则默认为不保存余料，跳过该余料
                    if (remnantLower == null || remnantLower.compareTo(BigDecimal.ZERO) <= 0) {
                        log.debug("物料[{}]未设置余料下限或余料下限为0，跳过余料长度[{}]", material.getProfileCode(), material.getRemnant());
                        continue;
                    }
                    
                    // 如果余料长度小于余料下限，则不保存该余料
                    if (BigDecimal.valueOf(material.getRemnant()).compareTo(remnantLower) < 0) {
                        log.debug("物料[{}]余料长度[{}]小于余料下限[{}]，跳过该余料", material.getProfileCode(), material.getRemnant(), remnantLower);
                        continue;
                    }
                } else {
                    // 如果找不到物料信息，默认不保存余料
                    log.warn("未找到物料[{}]的信息，跳过该余料", material.getProfileCode());
                    continue;
                }
                
                SurplusMaterialVO vo = new SurplusMaterialVO();
                vo.setProfileCode(material.getProfileCode());
                vo.setProfileName(material.getProfileName());
                vo.setSurplusLength(material.getRemnant());
                vo.setOptimizationSoftwareType(1);
                
                // 设置单位成本
                if (materialInfo.getUnitCost() != null) {
                    //余料单位成本 = 物料单位成本/物料长度 * 余料长度
                    vo.setUnitCost(materialInfo.getUnitCost().divide(BigDecimal.valueOf(material.getLength()),
                            2,
                            BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(vo.getSurplusLength())));
                }
                
                // 生成余料编号
                vo.setMaterialCode(material.getProfileCode() + "-" + material.getRemnant().intValue());
                
                // 设置物料类型为余料(5)
                vo.setMaterialType("5");
                
                // 查询物料信息获取规格和单位
                setMaterialInfo(vo);
                
                result.add(vo);
            }
        }
        
        return result;
    }
    
    /**
     * 根据型材编码查询物料信息并设置到VO中
     */
    private void setMaterialInfo(SurplusMaterialVO vo) {
        if (StringUtils.isNotBlank(vo.getProfileCode())) {
            com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<WmsMaterial> wrapper = 
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
            wrapper.eq(WmsMaterial::getMaterialCode, vo.getProfileCode());
            WmsMaterial material = wmsMaterialMapper.selectOne(wrapper);
            
            if (material != null) {
                vo.setSpecification(material.getSpecification());
                vo.setUnit(material.getUnit());
                
                // 如果没有名称，设置物料名称
                if (StringUtils.isBlank(vo.getProfileName())) {
                    vo.setProfileName(material.getMaterialName());
                }
            } else {
                // 如果没有找到物料信息，设置默认值
                if (StringUtils.isBlank(vo.getUnit())) {
                    vo.setUnit("");
                }
            }
        }
    }
    
    @Override
    public List<SurplusMaterialVO> processAndGroupSurplusMaterials(List<SurplusMaterialVO> surplusMaterials) {
        if (surplusMaterials == null || surplusMaterials.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 使用Map按余料编号分组
        Map<String, SurplusMaterialVO> materialMap = new HashMap<>();
        
        // 遍历所有余料
        for (SurplusMaterialVO material : surplusMaterials) {
            // 确保余料编号不为空
            if (StringUtils.isBlank(material.getMaterialCode())) {
                if (StringUtils.isNotBlank(material.getProfileCode()) && material.getSurplusLength() != null) {
                    material.setMaterialCode(material.getProfileCode() + "-" + material.getSurplusLength().intValue());
                } else {
                    continue;  // 跳过无法生成编号的记录
                }
            }
            
            if (materialMap.containsKey(material.getMaterialCode())) {
                // 已存在相同编号的余料，累加数量
                SurplusMaterialVO existingMaterial = materialMap.get(material.getMaterialCode());
                int quantity = 1;
                if (existingMaterial.getMaterialType() != null && existingMaterial.getMaterialType().equals("5")) {
                    try {
                        quantity = Integer.parseInt(existingMaterial.getUnit()) + 1;
                    } catch (NumberFormatException e) {
                        quantity = 2;  // 如果之前的值不是数字，设为2（原来的1加上新的1）
                    }
                } else {
                    quantity = 2;  // 第一次遇到重复时设为2
                }
                existingMaterial.setNum(String.valueOf(quantity));
            } else {
                // 新增记录
                material.setNum("1");  // 初始数量为1
                materialMap.put(material.getMaterialCode(), material);
            }
        }
        
        // 转换为列表返回
        return materialMap.values().stream().collect(Collectors.toList());
    }
    
    @Override
    public List<SurplusMaterialVO> filterSurplusByLowerLimit(List<SurplusMaterialVO> surplusMaterials) {
        if (surplusMaterials == null || surplusMaterials.isEmpty()) {
            return new ArrayList<>();
        }
        
        try {
            log.info("开始根据余料下限过滤余料信息，原始余料数量: {}", surplusMaterials.size());
            
            List<SurplusMaterialVO> filteredMaterials = new ArrayList<>();
            
            for (SurplusMaterialVO material : surplusMaterials) {
                try {
                    // 获取物料编码（去掉余料长度后缀）
                    String materialCode = material.getProfileCode();
                    if (StringUtils.isBlank(materialCode)) {
                        log.warn("余料物料编码为空，跳过过滤: {}", material.getMaterialCode());
                        continue;
                    }
                    
                    // 查询物料的余料下限
                    WmsMaterial wmsMaterial = wmsMaterialMapper.selectOne(
                        new QueryWrapper<WmsMaterial>().eq("material_code", materialCode)
                    );
                    
                    if (wmsMaterial == null) {
                        log.warn("未找到物料信息，保留余料: materialCode={}", materialCode);
                        filteredMaterials.add(material);
                        continue;
                    }
                    
                    // 检查余料下限
                    BigDecimal remnantLower = wmsMaterial.getRemnantLower();
                    if (remnantLower == null || remnantLower.compareTo(BigDecimal.ZERO) <= 0) {
                        // 如果没有设置余料下限或下限为0，则保留该余料
                        filteredMaterials.add(material);
                        log.debug("物料[{}]未设置余料下限，保留余料长度: {}", materialCode, material.getSurplusLength());
                    } else {
                        // 比较余料长度与下限
                        Double surplusLength = material.getSurplusLength();
                        if (surplusLength != null && surplusLength > remnantLower.doubleValue()) {
                            filteredMaterials.add(material);
                            log.debug("余料长度[{}]大于下限[{}]，保留余料: {}", surplusLength, remnantLower, materialCode);
                        } else {
                            log.debug("余料长度[{}]小于等于下限[{}]，过滤余料: {}", surplusLength, remnantLower, materialCode);
                        }
                    }
                    
                } catch (Exception e) {
                    log.error("过滤单个余料时发生异常，保留该余料: materialCode={}", material.getProfileCode(), e);
                    filteredMaterials.add(material);
                }
            }
            
            log.info("余料下限过滤完成，过滤前: {}，过滤后: {}", surplusMaterials.size(), filteredMaterials.size());
            return filteredMaterials;
            
        } catch (Exception e) {
            log.error("余料下限过滤失败", e);
            
            // 根据配置的处理策略决定如何处理失败
            if ("strict".equals(surplusInboundConfig.getFilterFailureStrategy())) {
                // 严格模式：抛出异常
                throw new JeecgBootException("余料下限过滤失败: " + e.getMessage());
            } else {
                // 宽松模式：返回原始列表
                log.warn("宽松模式下余料过滤失败，返回原始余料列表");
                return surplusMaterials;
            }
        }
    }
    
    @Override
    public List<SurplusMaterialVO> getValidSurplusMaterialsByOrderId(String orderId) {
        try {
            log.info("获取订单[{}]的有效余料信息", orderId);
            
            // 1. 获取原始余料信息
            List<SurplusMaterialVO> rawSurplusMaterials = getSurplusMaterialsByOrderId(orderId);
            if (rawSurplusMaterials.isEmpty()) {
                log.info("订单[{}]无余料信息", orderId);
                return new ArrayList<>();
            }
            
            // 2. 根据余料下限过滤
            List<SurplusMaterialVO> filteredMaterials = filterSurplusByLowerLimit(rawSurplusMaterials);
            
            // 3. 处理和分组余料
            List<SurplusMaterialVO> groupedMaterials = processAndGroupSurplusMaterials(filteredMaterials);
            
            log.info("订单[{}]有效余料信息获取完成，数量: {}", orderId, groupedMaterials.size());
            return groupedMaterials;
            
        } catch (Exception e) {
            log.error("获取订单[{}]有效余料信息失败", orderId, e);
            throw new JeecgBootException("获取有效余料信息失败: " + e.getMessage());
        }
    }
}